/*
 * pilua_pinfo.c
 *
 * Wireshark's interface to the Lua Programming Language
 *
 * (c) 2006, Luis E. Garcia Ontanon <luis@ontanon.org>
 * (c) 2008, Balint Reczey <balint.reczey@ericsson.com>
 * (c) 2011, Stig Bjorlykke <stig@bjorlykke.org>
 *
 * Wireshark - Network traffic analyzer
 * By Gerald Combs <gerald@wireshark.org>
 * Copyright 1998 Gerald Combs
 *
 * SPDX-License-Identifier: GPL-2.0-or-later
 */

#include <string.h>
#include <glib.h>

#include "packet_info.h"
#include "packet.h"

#include "wmem_strbuf.h"

#include "tvbuff.h"
#include "ftypes.h"
#include "crc16-tvb.h"
#include "crc32-tvb.h"

#include "pilua.h"


PILUA_CLASS_DEFINE(CRC, NOP);
/* CRC Checksum. */

PILUA_METHOD CRC_crc16ccitt(lua_State *L)
{
    Tvb tvb = checkTvb(L, 1);
    uint16_t crc16;

    crc16 = crc16_ccitt_tvb(tvb->pi_tvb, tvb_reported_length_remaining(tvb->pi_tvb, 0));

    lua_pushinteger(L, crc16);
    PILUA_RETURN(1);
}

PILUA_METHOD CRC_crc16x25(lua_State *L)
{
    Tvb tvb = checkTvb(L, 1);
    uint16_t crc16;

    crc16 = crc16_x25_ccitt_tvb(tvb->pi_tvb, tvb_reported_length_remaining(tvb->pi_tvb, 0));

    lua_pushinteger(L, crc16);
    PILUA_RETURN(1);
}

PILUA_METHOD CRC_crc16r3(lua_State *L)
{
    Tvb tvb = checkTvb(L, 1);
    uint16_t crc16;

    crc16 = crc16_r3_ccitt_tvb(tvb->pi_tvb, 0, tvb_reported_length_remaining(tvb->pi_tvb, 0));

    lua_pushinteger(L, crc16);
    PILUA_RETURN(1);
}

PILUA_METHOD CRC_crc16plain(lua_State *L)
{
#define PILUA_OPTARG_CRC_crc16plain_SEED 2 /* The seed value of the crcin. Default is 0xFFFF. */
    Tvb tvb = checkTvb(L, 1);
    uint16_t crc16;
    uint16_t seed = (int)luaL_optinteger(L, PILUA_OPTARG_CRC_crc16plain_SEED, 0xFFFF);

    crc16 = crc16_plain_tvb_offset_seed(tvb->pi_tvb, 0, tvb_reported_length_remaining(tvb->pi_tvb, 0), seed);

    lua_pushinteger(L, crc16);
    PILUA_RETURN(1);
}

PILUA_METHOD CRC_crc32ccitt(lua_State *L)
{
#define PILUA_OPTARG_CRC_crc32plain_SEED 2 /* The seed value of the crcin. Default is 0xFFFFFFFF. */
    Tvb tvb = checkTvb(L, 1);
    uint32_t crc32;
    uint32_t seed = (int)luaL_optinteger(L, PILUA_OPTARG_CRC_crc32plain_SEED, 0xFFFFFFFF);

    crc32 = crc32_ccitt_tvb_seed(tvb->pi_tvb, tvb_reported_length_remaining(tvb->pi_tvb, 0), seed);

    lua_pushinteger(L, crc32);
    PILUA_RETURN(1);
}

/* Gets registered as metamethod automatically by PILUA_REGISTER_CLASS/META */
static int CRC__gc(lua_State* L)
{

    return 0;
}

/* This table is ultimately registered as a sub-table of the class' metatable,
 * and if __index/__newindex is invoked then it calls the appropriate function
 * from this table for getting/setting the members.
 */
PILUA_METHODS CRC_methods[] = {
    PILUA_CLASS_FNREG(CRC, crc16ccitt),
    PILUA_CLASS_FNREG(CRC, crc16x25),
    PILUA_CLASS_FNREG(CRC, crc16r3),
    PILUA_CLASS_FNREG(CRC, crc16plain),
    PILUA_CLASS_FNREG(CRC, crc32ccitt),
    { NULL, NULL}
};

PILUA_META CRC_meta[] = {
    { NULL, NULL }
};

int CRC_register(lua_State* L)
{
    PILUA_REGISTER_CLASS(CRC);

    return 0;
}
